<!--
 * @Date: 2024-07-30 10:43:07
 * @Author: LiSong
 * @LastEditors: ljc
 * @LastEditTime: 2025-07-08 09:24:47
 * @Description: 表格数据源弹窗
-->
<template>
  <vxe-modal :="dialogAttrs"
    v-model="dialogStore.visible"
    @close="handleClose">
    <template #header>
      <div class="source-header">
        <div class="source-header-left"><span>{{ dialogAttrs.title }}</span></div>
        <div class="source-header-right">
          <el-button size="default"
            type="primary"
            @click="onToolsClick(`save:${modeTabsStore.active.toLowerCase()}`)">确定</el-button>
          <el-button size="default"
            type=""
            @click="handleClose"
            style="margin-right: 0;">取消</el-button>
        </div>
      </div>
    </template>
    <div class="source-wrapper">
      <div class="mode-tabs">
        <div class="mode-tabs__nav-wrap">
          <div v-for="(modeItem, index) in modeTabsStore.tabList"
            :key="index"
            :class="[
            'mode-tabs__item',
            modeItem.value === modeTabsStore.active ? 'active' : ''
          ]"
            @click="modeTabsChange(modeItem)">
            <span class="vertical">
              <span class="en">{{ modeItem.label.en }}</span>
              <span class="zh">{{ modeItem.label.zh }}</span>
            </span>
          </div>
        </div>
      </div>
      <div class="source-content">
        <VfLayoutLeftRight>
          <template #left>
            <SqlConfigPanel v-show="DataSourceType.SQL.equals(modeTabsStore.active)"
              ref="sqlModeRef"
              @save="onSqlSave"
              @analysis="onSqlAnalysis" />
            <ReqConfigPanel v-show="DataSourceType.REQ.equals(modeTabsStore.active)"
              ref="reqModeRef"
              @save="onReqSave"
              @analysis="onReqAnalysis" />
            <StaticConfigPanel v-show="DataSourceType.STA.equals(modeTabsStore.active)"
              ref="staticModeRef"
              @save="onStaticSave"
              @analysis="onStaticAnalysis" />
          </template>
          <template #right>
            <el-tabs class="table-tabs"
              v-model="tableTabsStore.active"
              @tabChange="tableTabsChange">
              <el-tab-pane name="field">
                <template #label>
                  <div class="table-tabs__label"><span>字段明细</span></div>
                </template>
                <FieldTable ref="fieldTableRef"
                  :="fieldTableAttrs" />
              </el-tab-pane>
              <el-tab-pane name="params"
                :disabled="DataSourceType.REQ.equals(modeTabsStore.active) || DataSourceType.STA.equals(modeTabsStore.active)">
                <template #label>
                  <div class="table-tabs__label"><span>参数明细</span></div>
                </template>
                <ParamTable ref="paramTableRef"
                  :="paramTableAttrs" />
              </el-tab-pane>
              <el-tab-pane name="preview">
                <template #label>
                  <div class="table-tabs__label"><span>数据预览</span></div>
                </template>
                <PreviewTable :="previewTableAttrs" />
              </el-tab-pane>
            </el-tabs>
          </template>
        </VfLayoutLeftRight>
      </div>
    </div>
  </vxe-modal>
</template>

<script setup>
import { VfLayoutLeftRight } from '@/components/vf-layout'
import SqlConfigPanel from './components/SqlConfigPanel.vue'
import ReqConfigPanel from './components/ReqConfigPanel.vue'
import StaticConfigPanel from './components/StaticConfigPanel.vue'
import { FieldTable, ParamTable, PreviewTable } from '@/components/tables'

import { reactive, provide, ref, nextTick } from 'vue';
import { XEUtils } from '@/utils'
import { VfMessage } from '@/utils/vf-utils'
import { baseAttrs } from '@/components/dialogs/cfg/base-cofig.js'

import { DataSourceType } from '@/base/pojo/DataSourceType.js'

// 对外触发定义的事件
const emits = defineEmits(['close', 'confirm']);
// 父级传递的对象参数

const props = defineProps({
  optionModel: { type: Object }
})
const setProvideData = () => {
  return {
    optionModel: props.optionModel
  }
}
// 用于提供可以被后代组件注入的值
provide('getTableConfigData', setProvideData);

// 弹窗属性配置
const dialogAttrs = reactive({
  ...baseAttrs,
  width: '96%',
  height: '90%',
  title: '表格数据源配置',
  className: 'vf-designer-dialog data-source-dialog',
  showClose: false,
  showFooter: false,
})
// 弹窗数据集对象
const dialogStore = reactive({
  visible: false,
})
// watch()
/** 打开弹窗 */
const handleOpen = () => {
  const { dataConfig } = props.optionModel
  // 设置数据模式
  modeTabsStore.active = dataConfig.mode
  tableTabsStore.active = tableTabsStore.defValue
  // 设置表格下拉选项
  setTableData(dataConfig)
  // 设置表格下拉选项
  setTableOptions(dataConfig)
  // 展示弹窗
  dialogStore.visible = true
}
/**
 * 保存数据的方法
 * 
 * @param params 参数
 */
const handleSave = (params) => {
  const { dataConfig } = props.optionModel;
  dataConfig.mode = modeTabsStore.active;
  if (validateData()) {
    const finalColumns = getTableData()
    dataConfig.fieldColumns = finalColumns.fieldColumns;
    dataConfig.paramColumns = finalColumns.paramColumns;
    props.optionModel.dataConfig = { ...dataConfig, ...params };
    handleClose();
    emits('confirm');
  }
}
/**
 * 关闭弹窗
 */
const handleClose = () => {
  dialogStore.visible = false
  const $sqlModeRef = sqlModeRef.value;
  if ($sqlModeRef) $sqlModeRef.resetAnalyseInfo()
}

/**
 * 保存按钮点击
 * 
 * @param type 类型
 */
const onToolsClick = (type) => {
  const $sqlModeRef = sqlModeRef.value;
  const $reqModeRef = reqModeRef.value;
  const $staticModeRef = staticModeRef.value;
  switch (type) {
    case 'save:sql':
      $sqlModeRef.saveClick()
      break;
    case 'save:req':
      $reqModeRef.saveClick()
      break;
    case 'save:sta':
      $staticModeRef.saveClick()
      break;
    default:
      break;
  }
}

// 数据源模式的tabs数据集
const modeTabsStore = reactive({
  active: DataSourceType.SQL.value,
  tabList: [
    DataSourceType.SQL.getPkg(),
    DataSourceType.REQ.getPkg(),
    DataSourceType.STA.getPkg(),
  ],
})
/**
 * 数据源模式切换
 * 
 * @param modeItem 选择的模式
 */
const modeTabsChange = (modeItem) => {
  modeTabsStore.active = modeItem.value
  tableTabsStore.active = tableTabsStore.defValue
}

// 字段表格Ref对象
const fieldTableRef = ref(null)
// 参数表格Ref对象
const paramTableRef = ref(null)
// 选项卡中表格数据集
const tableTabsStore = reactive({
  active: 'field',
  defValue: 'field'
})
// 字段表格的属性
const fieldTableAttrs = reactive({
  fieldOptions: []
})
// 参数表格的属性
const paramTableAttrs = reactive({
  fieldOptions: []
})
// 预览表格的属性
const previewTableAttrs = reactive({
  data: [],
  columns: [],
})
/**
 * 右侧选项卡切换
 * 
 * @param name 选择的tab名称
 */
const tableTabsChange = (name) => {
  tableTabsStore.active = name
  if (name === 'preview') {
    const resultData = fieldTableRef.value.getPreviewTableData();
    Object.assign(previewTableAttrs, { ...resultData })
  }
}

/**
 * 获取表格数据
 */
const getTableData = () => {
  const result = {
    fieldColumns: [], paramColumns: []
  }
  if (fieldTableRef.value) {
    result.fieldColumns = fieldTableRef.value.getTableData()
  }
  // 如果不是SQL模式，参数表格不做存储
  if (DataSourceType.SQL.equals(modeTabsStore.active)) {
    if (paramTableRef.value) {
      result.paramColumns = paramTableRef.value.getTableData()
    }
  }
  return result
}
/**
 * 设置表格数据
 * 
 * @param { Object } { fieldColumns, paramColumns }
 * @param {Boolean} isCover 是否覆盖 默认false-否
 */
const setTableData = ({ fieldColumns = [], paramColumns = [] }, isCover = false) => {
  nextTick(() => {
    setTimeout(() => {
      if (fieldTableRef.value && fieldColumns) {
        fieldTableRef.value.setTableData(fieldColumns, isCover);
      }
      if (paramTableRef.value && paramColumns) {
        paramTableRef.value.setTableData(paramColumns, isCover);
      }
    }, 250)
  });
}

/**
 * 校验表格数据
 */
const validateData = () => {
  let flag = true
  // 字段表格校验
  if (fieldTableRef.value) {
    flag = flag && fieldTableRef.value.validateTableData()
  }
  // 如果是SQL模式，参数表格校验
  if (DataSourceType.SQL.equals(modeTabsStore.active)) {
    if (paramTableRef.value) {
      flag = flag && paramTableRef.value.validateTableData()
    }
  }
  return flag
}
/**
 * 设置表格选项
 *
 * @param { Object } { fieldList, paramList }
 */
const setTableOptions = ({ fieldList, paramList }) => {
  fieldTableAttrs.fieldOptions = XEUtils.clone(fieldList, true);
  paramTableAttrs.fieldOptions = XEUtils.clone(paramList, true);
}

// sql模式面板的Ref
const sqlModeRef = ref(null);
/**
 * SQL模式保存方法
 * 
 * @param params 参数
 */
const onSqlSave = (params) => {
  // 清除接口数据配置
  resetReqConfig()
  handleSave(params)
}
/**
 * SQL模式解析方法
 * @param result 参数
 */
const onSqlAnalysis = (result, isCover) => {
  setTableData(result, isCover)
  setTableOptions(result, isCover)
}
/**
 * 重置SQL模式参数信息
 */
const resetSqlConfig = () => {
  props.optionModel.dataConfig.sqlConfig = {
    content: ''
  }
  // 清除参数表格的配置信息
  props.optionModel.dataConfig.paramList = []
  props.optionModel.dataConfig.paramColumns = []
}


// sql模式面板的Ref
const reqModeRef = ref(null);
/**
 * REQ模式保存方法
 * 
 * @param params 参数
 */
const onReqSave = (params) => {
  // 清除SQL模式的数据
  resetSqlConfig()
  handleSave(params)
}
/**
 * REQ模式解析方法
 * 
 * @param params 参数
 */
const onReqAnalysis = (params) => {
  VfMessage.info('功能正在开发中......')
}
/**
 * 重置REQ模式参数信息
 */
const resetReqConfig = () => {
  // 清除接口数据配置
  props.optionModel.dataConfig.reqConfig = {
    url: '',
    method: 'POST',
    params: '',
    paramsType: 'data',
  }
}
// 静态数据模式面板的Ref
const staticModeRef = ref(null)
/** 
 * 静态数据回调
 * @param result 数据
 */
const onStaticSave = (result) => {
  handleSave(result)
}
const onStaticAnalysis = (result, isCover) => {
  setTableData(result, isCover)
  setTableOptions(result, isCover)
}
defineExpose({
  handleOpen
})

</script>

<style lang="scss" scoped>
.source-header {
  display: flex;
  align-items: center;
  padding: 12px;
  width: 100%;
  &-left {
    margin-right: 10px;
  }
  &-right {
    margin-left: auto;
    padding-right: 0;
  }
}
.source-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  display: inline-flex;
  .mode-tabs {
    width: 42px;
    display: flex;
    flex-direction: column;
    &__nav-wrap {
      flex: 1;
      min-height: 300px;
      position: relative;
      background-color: #f5f7fa;
    }
    &__item {
      padding: 10px;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      list-style: none;
      font-size: var(--el-font-size-base);
      font-weight: 500;
      color: var(--el-text-color-primary);
      position: relative;
      cursor: pointer;
      &:hover {
        color: var(--el-color-primary);
      }
      &.active {
        color: var(--el-color-primary);
        border: 1px solid transparent;
        border-top: none;
        border-bottom: none;
        border-color: transparent;
        border-top-color: #d1dbe5;
        border-bottom-color: #d1dbe5;
        background-color: #ffffff;
      }
      .vertical {
        writing-mode: vertical-rl;
        text-orientation: upright;
        letter-spacing: 5px;
        .en {
          letter-spacing: -5px;
          margin-bottom: 8px;
        }
      }
    }
    &__tool-warp {
      position: relative;
    }
  }
  .source-content {
    flex: 1;
    min-width: 200px;
  }
  .table-tabs {
    height: 100%;
    &__label {
      padding: 0 20px;
    }
    display: flex;
    :deep(.el-tabs__header) {
      margin: 0;
      background-color: #f5f7fa;
      .el-tabs__item {
        padding: 0;
      }
    }
    :deep(.el-tabs__content) {
      flex: 1;
      min-height: 100px;
      padding: 8px;
      padding-top: 0;
      .el-tab-pane {
        height: 100%;
      }
    }
  }
}
</style>
<style lang="scss">
.data-source-dialog {
  &.vxe-modal--wrapper .vxe-modal--content {
    padding: 0;
  }
}
</style>
